function rslice_vslice_velocity_redraw( hObject, options )
% RSLICE_VSLICE_VELOCITY_REDRAW:  redraws the vertical velocity slice
%
% PARAMETERS
% Input:
%     hObject:  this should be the hslice figure
%     options:
%         Optional.  If given, this structure will have flags that
%         override the default flags.
%
%
% The line
%
%     gdata = guidata ( hObject );
%
% retrieves a global data structure used to store information.
% This routine sets a field of gdata called "vslice_vel_data".  This 
% field is a structure itself and contains the following fields.
%
%     vslice_line_handles:
%         Four lines that depict the vslice velocity line on the 
%         hslice figure.  The first is a thin high resolution line.
%         The second is a thick high resolution line that fits 
%         underneath the first.  The third is a line of asterisks
%         at the control points defining the line.  These asterisks
%         fit into the fourth line, which is just a set of 'o'
%         markers.
%     spline_x, spline_y:
%         Structure that define the splined lines whose handles 
%         are stored in "vslice_line_handles".
%     vx:
%         2D array.  x array along the velocity slice
%     vz:
%         2D array.  z (or depth) array along the velocity slice
%     vdata:
%         2D array. This is the velocity slice itself, vdata = u + i*v
%     transect_dist:
%         1D array, cumulative distance along the slice at the surface.
%     control_pt_x, control_pt_y:
%         points that the user specified to determine the vslice line
%     hires_x, hires_y:
%         splined high resolution points along the vslice line
% 
% Calls:
%     rslice_get_grid
%




%
% Supply defaults for any option not specified.
options = supply_default_options ( options );


gdata = guidata ( hObject );
handles = guihandles ( hObject );



if options.redraw_surface_line
	redraw_the_surface_line(gdata);
	return
end



%
% Does the figure even exist?  If not, then create it.
try
	get ( gdata.vslice_vel_figure, 'visible' );
catch
	gdata.vslice_vel_figure = vslice_vel;
	set ( gdata.vslice_vel_figure, 'visible', 'off' );
end
vdata.parent = hObject;
guidata ( gdata.vslice_vel_figure, vdata );


% Turn off zooming
zoom ( gdata.hslice_figure, 'off' );

[control_pts, hi_res_pts, spx, spy, options] = get_uv_locations ( hObject, options );

[vx,vz,vdata,vslice_angle,transect_dist] = acquire_vslice_uv_data ( gdata, hi_res_pts, options );

[lrx, lrz] = acquire_vslice_line_bathymetry ( hi_res_pts, control_pts, transect_dist, vz );

[tv, nv] = w2tn ( vdata, hi_res_pts.x, hi_res_pts.y, vslice_angle );

set ( gdata.vslice_vel_figure, 'visible', 'on' );

figure ( gdata.vslice_vel_figure );
render_vslice_velocity ( gdata, vx, vz, lrx, lrz, tv, nv, transect_dist );


%
% STore the data for the next time around.
vslice_line_handles = findobj ( gdata.horizontal_slice_axis, 'Tag', 'VSlice Velocity Line' );
vslice_vel_data.vx = vx;
vslice_vel_data.vz = vz;
vslice_vel_data.vdata = vdata;
vslice_vel_data.vslice_angle = vslice_angle;
vslice_vel_data.vslice_line_handles = vslice_line_handles;
vslice_vel_data.spline_x = spx;
vslice_vel_data.spline_y = spy;
vslice_vel_data.transect_dist = transect_dist;
vslice_vel_data.control_pt_x = control_pts.x;
vslice_vel_data.control_pt_y = control_pts.y;
vslice_vel_data.hires_x = hi_res_pts.x;
vslice_vel_data.hires_y = hi_res_pts.y;

gdata.vslice_vel_data = vslice_vel_data;

guidata ( hObject, gdata );


return








%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% REDRAW_THE_SURFACE_LINE
%
%   Just redraw the control line that the user used to specify the vertical 
%   slicing.
function vslice_line_handles = redraw_the_surface_line ( gdata )

%
% Does it even exist?
if ~isfield ( gdata, 'vslice_vel_data' )
	return
end

%
% Just retrieve the previously stored line data.
spx = gdata.vslice_vel_data.spline_x;
spy = gdata.vslice_vel_data.spline_y;

vslice_control_pt_x = gdata.vslice_vel_data.control_pt_x;
vslice_control_pt_y = gdata.vslice_vel_data.control_pt_y;
vslice_hires_x = gdata.vslice_vel_data.hires_x;
vslice_hires_y = gdata.vslice_vel_data.hires_y;
vslice_hires_x = vslice_hires_x(:);
vslice_hires_y = vslice_hires_y(:);

axes ( gdata.horizontal_slice_axis );
hold on
[vslice_line_handles] = draw_vslice_line ( vslice_control_pt_x, vslice_control_pt_y, spx, spy );

return






%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% SUPPLY_DEFAULT_OPTIONS
%
% Sometime the options structure doesn't have everything listed.  Fill in 
% default values for those missing options.
function options = supply_default_options ( options )
% 
%
% Override the defaults here.

if ~isfield ( options, 'get_new_line' )
	options.get_new_line = 0;
end

if ~isfield ( options, 'redraw_surface_line' )
	options.redraw_surface_line = 0;
end

if ~isfield ( options, 'use_vslice_line' )
	options.use_vslice_line = 0;
end

if ~isfield ( options, 'retrieve_new_data' )
	options.retrieve_new_data = 0;
end



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% GET_UV_LOCATIONS
%
% There are a few different situations for where we acquire the locations of the
% velocity slice line.
function [control_pts, hi_res_pts, spx, spy, options] = get_uv_locations ( hObject, options )

gdata = guidata ( hObject );
handles = guihandles ( hObject );
vslice_handles = guihandles ( gdata.vslice_vel_figure );
vslice_line_handles = findobj ( gdata.horizontal_slice_axis, 'Tag', 'VSlice Velocity Line' );

if options.use_vslice_line


	% Does it already exist?  If not, we need to retrieve uv data later on.
	if ~isfield ( gdata, 'vslice_vel_data' )
		options.retrieve_new_data = 1;
	end



	%
	% Get two points on the hslice axis and feed this into
	% rslice_xslice
	%axes ( handles.horizontal_slice_axis );
	%the_clim = get ( gca, 'clim' );

	spx = gdata.vslice_data.spline_x;
	spy = gdata.vslice_data.spline_y;

	control_pts.x = gdata.vslice_data.control_pt_x(:);
	control_pts.y = gdata.vslice_data.control_pt_y(:);
	hi_res_pts.x = gdata.vslice_data.hires_x(:);
	hi_res_pts.y = gdata.vslice_data.hires_y(:);

	delete (vslice_line_handles);

	vslice_line_handles = draw_vslice_line ( control_pts.x, control_pts.y, spx, spy );

	set ( vslice_line_handles, 'Tag', 'Vslice Velocity Line' );


elseif options.get_new_line

	%
	% Does it already exist?  If so, get rid of it.  We need a new one.
	if isfield ( gdata, 'vslice_vel_data' )
		if isfield ( gdata.vslice_vel_data, 'vslice_line_handles' )
			try
				delete ( gdata.vslice_vel_data.vslice_line_handles );
			end
		end
	end



	%
	% Get two points on the hslice axis and feed this into
	% rslice_xslice
	axes ( handles.horizontal_slice_axis );
	the_clim = get ( gca, 'clim' );

	[spx, spy, vslice_line_handles] = acquire_vslice_line;

	set ( vslice_line_handles, 'Tag', 'Vslice Velocity Line' );

	control_pts.x = get ( vslice_line_handles(3), 'XData' );
	control_pts.y = get ( vslice_line_handles(3), 'YData' );
	hi_res_pts.x = get ( vslice_line_handles(1), 'XData' );
	hi_res_pts.y = get ( vslice_line_handles(1), 'YData' );
	hi_res_pts.x = hi_res_pts.x(:);
	hi_res_pts.y = hi_res_pts.y(:);

else

	%
	% Just retrieve the previously stored line data.
	spx = gdata.vslice_vel_data.spline_x;
	spy = gdata.vslice_vel_data.spline_y;

	control_pts.x = gdata.vslice_vel_data.control_pt_x;
	control_pts.y = gdata.vslice_vel_data.control_pt_y;
	hi_res_pts.x = gdata.vslice_vel_data.hires_x;
	hi_res_pts.y = gdata.vslice_vel_data.hires_y;
	hi_res_pts.x = hi_res_pts.x(:);
	hi_res_pts.y = hi_res_pts.y(:);

	axes ( gdata.horizontal_slice_axis );
	hold on
	[vslice_line_handles] = draw_vslice_line ( vslice_control_pt_x, vslice_control_pt_y, spx, spy );

end

return




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% ACQUIRE_VSLICE_DATA
%
% There are a few difference conditions under which we acquire the vertical uv
% data.
function [vx,vz,vdata, vslice_angle,transect_dist] = acquire_vslice_uv_data ( gdata, hi_res_pts, options )

if options.retrieve_new_data

	if strcmp ( gdata.rslice_grid.coordsys, 'geographic' )

		if gdata.rslice_grid.have_angle
			%
			% Get angle
			gdata_angle = gdata;
			gdata_angle = setfield ( gdata_angle, 'varname', 'angle' );
			gdata_angle.varinfo = gdata.rslice_grid.angle;
			gdata_angle.dim_type = 'YX';
			gdata_angle.z_type = [];
			[grid.x,grid.y,grid.z,grid.mask,status] = rslice_get_grid ( gdata_angle );
			[x_a,z_a,vslice_angle,transect_dist] = rslice_xslice (hi_res_pts.x, hi_res_pts.y, grid, gdata_angle );
		else
			vslice_angle = [];
		end

	else
		vslice_angle = [];
	end

	%
	% Get u
	gdata_u = gdata;
	gdata_u = setfield ( gdata_u, 'varname', 'u' );
	gdata_u.varinfo = gdata.velocity.u_varinfo;
	gdata_u.dim_type = 'TZYX';
	gdata_u.z_type = 's_rho';
	[grid.x,grid.y,grid.z,grid.mask,status] = rslice_get_grid ( gdata_u );
	[x_u,z_u,u_data,transect_dist] = rslice_xslice (hi_res_pts.x, hi_res_pts.y, grid, gdata_u );

	%
	% Get v
	gdata_v = gdata;
	gdata_v = setfield ( gdata_u, 'varname', 'v' );
	gdata_v.varinfo = gdata.velocity.v_varinfo;
	gdata_v.dim_type = 'TZYX';
	gdata_v.z_type = 's_rho';
	[grid.x,grid.y,grid.z,grid.mask,status] = rslice_get_grid ( gdata_v );
	[x_v,z_v,v_data,transect_dist] = rslice_xslice (hi_res_pts.x, hi_res_pts.y, grid, gdata_v );

	vx = x_u;
	vz = z_u;
	vdata = u_data + sqrt(-1)*v_data;


else

	%
	% Just use what should already be available to us.
	vx = gdata.vslice_vel_data.vx;
	vz = gdata.vslice_vel_data.vz;
	vdata = gdata.vslice_vel_data.vdata;
	vslice_angle = gdata.vslice_vel_data.vslice_angle;
	transect_dist = gdata.vslice_vel_data.transect_dist;

end






%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% ACQUIRE_VSLICE_LINE_BATHYMETRY
function [lrx, lrz] = acquire_vslice_line_bathymetry ( hi_res_pts, control_pts, transect_dist, vz )

%
% figure out where the control points fall onto the bottom
Nh = length(hi_res_pts.x);
Nl = length(control_pts.x);
t = linspace ( 0, 1, Nh )';
t_inds = round ( linspace ( 1, Nh, Nl ) );
t_control_pts = t(t_inds);

cpsx = spline ( t, [0; transect_dist(:); 0] );
lrx = ppval ( cpsx, t_control_pts );

cpsz = spline ( t, [0; vz(end,:)'; 0] );
lrz = ppval ( cpsz, t_control_pts );

return





%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% RENDER_VSLICE_VELOCITY
%
% Go thru the motions of drawing everything now that we have all the information.
function render_vslice_velocity ( gdata, vx, vz, lrx, lrz, tan_v, norm_v, transect_dist )

vslice_handles = guihandles ( gdata.vslice_vel_figure );

figure ( gdata.vslice_vel_figure );
prior_h = findobj ( gdata.vslice_vel_figure, 'type', 'axes' );
delete(prior_h);

%
% Figure out what color limits.  If there are already preset
% color limits, then use those.  Otherwise try to figure them
% out from the initial set of data.
cmin_val = str2double ( get ( vslice_handles.cmin_edit, 'String' ) );
cmax_val = str2double ( get ( vslice_handles.cmax_edit, 'String' ) );
if ( isnan(cmin_val) | isnan(cmax_val) )
	cmax_val = max( [tan_v(:); norm_v(:)] );
	cmin_val = min( [tan_v(:); norm_v(:)] );
end

%
% Setting the CLim property will croak if the limits are the same.
if (isnan(cmin_val) & isnan(cmax_val))
	cmin_val = 0; 
	cmax = 1;
end
if cmin_val == cmax_val
	if cmin_val == 0
		cmax_val = 1;
	else
		cmax_val = cmin_val + 1;
	end
end

clim = [cmin_val cmax_val];

%
% Set the color limits for next time
set ( vslice_handles.cmin_edit, 'String', num2str(cmin_val) );
set ( vslice_handles.cmax_edit, 'String', num2str(cmax_val) );


%
% Get the units
v_units = '';
for k = 1:length(gdata.velocity.u_varinfo.Attribute)
	if strcmp ( gdata.velocity.u_varinfo.Attribute(k).Name, 'units' )
		v_units = gdata.velocity.u_varinfo.Attribute(k).Value;
	end
end

%
% tangential velocity
tax = axes ( 'position', [0.05 0.15 0.35 0.8] );
pcolorjw ( vx, vz, tan_v ); shading flat; 

set ( tax, 'CLim', clim );
title_string = sprintf ( 'Tangential Velocity:  %s', v_units );
title_handle = title ( title_string );
hold on
h1 = plot ( lrx, lrz, 'o' );
set ( h1, 'MarkerSize', 8 );
set ( h1, 'Color', 'k' );
h2 = plot ( lrx, lrz, 'w*' );
h3 = plot ( transect_dist, vz(end,:) );

%
% Make sure that all the handles belong to the vslice_vel figure
set ( tax, 'Parent', gdata.vslice_vel_figure );

%
% Draw the normal velocity
nax = axes ( 'position', [0.50 0.15 0.35 0.8] );
pcolorjw ( vx, vz, norm_v ); shading flat; 
set ( nax, 'CLim', clim );
title_string = sprintf ( 'Normal Velocity:  %s', v_units );
title_handle = title ( title_string );
hold on
h1 = plot ( lrx, lrz, 'o' );
set ( h1, 'MarkerSize', 8 );
set ( h1, 'Color', 'k' );
h2 = plot ( lrx, lrz, 'w*' );
h3 = plot ( transect_dist, vz(end,:) );

cax = colorbar;
set ( cax, 'Position', [0.88 0.15 0.05 0.8] );


%
% Make sure that all the handles belong to the vslice_vel figure
set ( nax, 'Parent', gdata.vslice_vel_figure );
set ( cax, 'Parent', gdata.vslice_vel_figure );

